package com.xinyue.server.framework.handlermapping;

import com.xinyue.server.framework.common.GameLogicException;
import com.xinyue.server.framework.common.IGameServerError;
import com.xinyue.server.framework.message.GameMessageHeader;
import com.xinyue.server.framework.message.GameMessagePackage;
import com.xinyue.server.framework.message.GameMessageType;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author 王广帅
 * @date 2021年01月26日 4:26 下午
 */
public class GameChannelContext {
    private static final Logger logger = LoggerFactory.getLogger(GameChannelContext.class);
    private GameMessageHeader requestHeader;
    private ChannelHandlerContext nettyCtx;

    public GameChannelContext(ChannelHandlerContext nettyCtx, GameMessageHeader requestHeader) {
        this.requestHeader = requestHeader;
        this.nettyCtx = nettyCtx;
    }

    public void writeAndFlush(IGameMessage response) {
        this.writeAndFlush(this.requestHeader, response);
    }

    public void writeAndFlush(IGameServerError gameError) {
        this.writeAndFlush(this.requestHeader, gameError.getErrorCode(), gameError.getErrorMsg());
    }

    public void writeAndFlush(int errorCode, String errorMsg) {
        this.writeAndFlush(this.requestHeader, errorCode, errorMsg);
    }

    private void writeAndFlush(GameMessageHeader requestHeader, IGameMessage gameMessage) {
        GameMessageHeader header = getResponseHeader(requestHeader);
        GameMessagePackage gameMessagePackage = new GameMessagePackage();
        gameMessagePackage.setHeader(header);
        gameMessagePackage.setBody(gameMessage);
        nettyCtx.writeAndFlush(gameMessagePackage);
    }

    private void writeAndFlush(GameMessageHeader requestHeader, int errorCode, String errorMsg) {
        GameMessageHeader responseHeader = new GameMessageHeader();
        responseHeader.setRequestId(requestHeader.getRequestId());
        responseHeader.setLogicMessageId(requestHeader.getLogicMessageId());
        responseHeader.setCreateTime(System.currentTimeMillis());
        responseHeader.setErrorCode(errorCode);
        responseHeader.setErrorMsg(errorMsg);
        responseHeader.setMessageType(GameMessageType.RESPONSE);
        GameMessagePackage gameMessagePackage = new GameMessagePackage();
        gameMessagePackage.setHeader(responseHeader);
        nettyCtx.writeAndFlush(gameMessagePackage);
    }

    private GameMessageHeader getResponseHeader(GameMessageHeader requestHeader) {
        GameMessageHeader responseHeader = new GameMessageHeader();
        responseHeader.setRequestId(requestHeader.getRequestId());
        responseHeader.setLogicMessageId(requestHeader.getLogicMessageId());
        responseHeader.setCreateTime(System.currentTimeMillis());
        responseHeader.setMessageType(GameMessageType.RESPONSE);
        return responseHeader;

    }

    public void writeAndFlush(Throwable exception) {
        logger.error("服务器异常", exception);
        if (exception instanceof GameLogicException) {
            GameLogicException logicException = (GameLogicException) exception;
            IGameServerError serverError = logicException.getServerError();
            writeAndFlush(serverError);
        } else {
            writeAndFlush(-1, "服务内部器错误," + exception.getMessage());
        }
    }

    public ChannelHandlerContext getNettyCtx() {
        return nettyCtx;
    }

}
